﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YRevitJig;

namespace YArchitech.Plumbing.ExtendElementSet
{
	public class StretchElementsJig : XLineJig, IDisposable
	{
		public List<YJKLine> OutSideLines { get; set; }

		public List<YJKLine> InSideLines { get; set; }

		public new XYZ StartPoint { get; set; }

		public XYZ MovingVector { get; set; }

		public UIDocument UIDoc { get; set; }

		public StretchElementsJig(UIDocument uiDoc) : base(uiDoc)
		{
			this.UIDoc = uiDoc;
		}

		public new double PickEndPoint(XYZ ptStart, string strPrompt = "请选择拉伸（拖动）终点：")
		{
			double result = 0.0;
			try
			{
				this.StartPoint = ptStart;
				base.EndPoint = base.UiDoc.Selection.PickPoint(strPrompt);
				base.EndPoint = base.GetResetPoint(this.StartPoint, base.EndPoint);
				result = base.EndPoint.DistanceTo(this.StartPoint);
			}
			catch
			{
				if (this.m_prompDlg != null && base.CmdEndType == XUiJigBase.ECmdEndType.eEnter)
				{
					base.CmdEndType = XUiJigBase.ECmdEndType.eOther;
					XYZ ptUser = base.Client2Revit(this.m_ptCur);
					ptUser = base.GetResetPoint(this.StartPoint, ptUser);
					result = Convert.ToDouble(this.m_prompDlg.GetInputValue()) / 304.8;
				}
				else
				{
					base.EndPoint = null;
				}
			}
			return result;
		}

		public override void Draw(PaintEventArgs paintEventArgs)
		{
			base.Draw(paintEventArgs);
			if (!this.m_ptCur.IsEmpty && paintEventArgs != null && this.StartPoint != null)
			{
				try
				{
					if (this.ElementSetIsMovable(this.OutSideLines))
					{
						XYZ xyz = base.Client2Revit(this.m_ptCur);
						XYZ xyz2 = new XYZ(xyz.X, xyz.Y, this.StartPoint.Z);
						MovingDirection movingDirection = MovingDirection.undefined;
						XYZ xyz3;
						if (this.HorizontalLine == null && this.VerticalLine == null)
						{
							xyz3 = this.GetAxisPoint(this.UIDoc, xyz2, this.StartPoint);
						}
						else
						{
							xyz3 = this.GetHoriOrVertPoint(this.UIDoc, xyz2, this.StartPoint, ref movingDirection);
						}
						if (xyz3 != null)
						{
							xyz2 = xyz3;
						}
						this.MovingVector = xyz2 - this.StartPoint;
						XGraphics g = new XGraphics(paintEventArgs.Graphics, base.JigPen);
						if (this.OutSideLines != null)
						{
							foreach (YJKLine hyline in this.OutSideLines)
							{
								XYZ point = hyline.StartPoint;
								if (movingDirection == MovingDirection.Horizontal && this.HorizontalLine != null && this.HorizontalLine.IsVertical(hyline.Line))
								{
									point = hyline.StartPoint.Add(this.MovingVector);
								}
								if (movingDirection == MovingDirection.Vertical && this.VerticalLine != null && this.VerticalLine.IsVertical(hyline.Line))
								{
									point = hyline.StartPoint.Add(this.MovingVector);
								}
								XYZ point2 = hyline.EndPoint.Add(this.MovingVector);
								new XLine2D(base.Revit2Client(point), base.Revit2Client(point2)).Draw(g);
							}
						}
						if (this.InSideLines != null)
						{
							foreach (YJKLine hyline2 in this.InSideLines)
							{
								XYZ point = hyline2.StartPoint.Add(this.MovingVector);
								XYZ point2 = hyline2.EndPoint.Add(this.MovingVector);
								new XLine2D(base.Revit2Client(point), base.Revit2Client(point2)).Draw(g);
							}
						}
					}
				}
				catch (Exception ex)
				{
					ex.ToString();
				}
			}
		}

		public void GetHoriAndVertLines()
		{
			try
			{
				if (this.OutSideLines != null && this.OutSideLines.Count > 0)
				{
					this.HorizontalLine = this.OutSideLines[0];
					foreach (YJKLine hyline in this.OutSideLines)
					{
						if (this.HorizontalLine.IsVertical(hyline.Line))
						{
							this.VerticalLine = hyline;
							break;
						}
					}
					if (this.VerticalLine == null)
					{
						this.VerticalLine = this.GetNormalVecLine(this.HorizontalLine);
					}
				}
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
		}

		protected bool ElementSetIsMovable(List<YJKLine> lineSet)
		{
			bool flag = true;
			if (lineSet != null && lineSet.Count > 0)
			{
				YJKLine hyline = lineSet[0];
				foreach (YJKLine hyline2 in lineSet)
				{
					flag &= (hyline.IsParallel(hyline2.Line) || hyline.IsVertical(hyline2.Line));
				}
			}
			return flag;
		}

		protected XYZ GetHoriOrVertPoint(UIDocument uiDoc, XYZ ptUser, XYZ ptOrigin, ref MovingDirection directron)
		{
			if (ptUser.DistanceTo(ptOrigin) < 0.0032808398950131233)
			{
				return null;
			}
			if (this.HorizontalLine != null)
			{
				XYZ xyzpoint = Line.CreateUnbound(ptOrigin, this.HorizontalLine.EndPoint - this.HorizontalLine.StartPoint).Project(ptUser).XYZPoint;
				if (xyzpoint.DistanceTo(ptOrigin) > 0.1 && this.Get3PtAngle(xyzpoint, ptOrigin, ptUser) < 0.78539816339744828)
				{
					directron = MovingDirection.Horizontal;
					return xyzpoint;
				}
			}
			if (this.VerticalLine != null)
			{
				XYZ xyzpoint = Line.CreateUnbound(ptOrigin, this.VerticalLine.EndPoint - this.VerticalLine.StartPoint).Project(ptUser).XYZPoint;
				if (xyzpoint.DistanceTo(ptOrigin) > 0.1 && this.Get3PtAngle(xyzpoint, ptOrigin, ptUser) < 0.78539816339744828)
				{
					directron = MovingDirection.Vertical;
					return xyzpoint;
				}
			}
			return null;
		}

		protected XYZ GetAxisPoint(UIDocument uiDoc, XYZ ptUser, XYZ ptOrigin)
		{
			if (ptUser.DistanceTo(ptOrigin) < 0.0032808398950131233)
			{
				return null;
			}
			Autodesk.Revit.DB.View activeView = uiDoc.ActiveView;
			XYZ xyzpoint = Line.CreateUnbound(ptOrigin, activeView.RightDirection).Project(ptUser).XYZPoint;
			if (xyzpoint.DistanceTo(ptOrigin) > 0.1 && this.Get3PtAngle(xyzpoint, ptOrigin, ptUser) < 0.052359877559829883)
			{
				return xyzpoint;
			}
			xyzpoint = Line.CreateUnbound(ptOrigin, activeView.UpDirection).Project(ptUser).XYZPoint;
			if (xyzpoint.DistanceTo(ptOrigin) > 0.1 && this.Get3PtAngle(xyzpoint, ptOrigin, ptUser) < 0.052359877559829883)
			{
				return xyzpoint;
			}
			Transform transform = Transform.CreateRotation(activeView.ViewDirection, 0.78539816339744828);
			XYZ xyz = transform.OfVector(activeView.RightDirection);
			xyzpoint = Line.CreateUnbound(ptOrigin, xyz).Project(ptUser).XYZPoint;
			if (xyzpoint.DistanceTo(ptOrigin) > 0.1 && this.Get3PtAngle(xyzpoint, ptOrigin, ptUser) < 0.052359877559829883)
			{
				return xyzpoint;
			}
			xyz = transform.OfVector(activeView.UpDirection);
			xyzpoint = Line.CreateUnbound(ptOrigin, xyz).Project(ptUser).XYZPoint;
			if (xyzpoint.DistanceTo(ptOrigin) > 0.1 && this.Get3PtAngle(xyzpoint, ptOrigin, ptUser) < 0.052359877559829883)
			{
				return xyzpoint;
			}
			return null;
		}

		public YJKLine GetNormalVecLine(YJKLine originalLine)
		{
			XYZ xyz = originalLine.EndPoint - originalLine.StartPoint;
			XYZ xyz2 = this.StartPoint.Add(xyz / 2.0);
			XYZ xyz3 = new XYZ(0.0, 0.0, 1.0).CrossProduct(xyz);
			XYZ end = xyz2.Add(xyz3);
			return new YJKLine(xyz2, end);
		}

		protected double Get3PtAngle(XYZ pt1, XYZ ptOrigin, XYZ pt2)
		{
			XYZ xyz = pt1 - ptOrigin;
			XYZ xyz2 = pt2 - ptOrigin;
			return xyz.AngleTo(xyz2);
		}

		protected YJKLine HorizontalLine;

		protected YJKLine VerticalLine;
	}
}
